home *** CD-ROM | disk | FTP | other *** search
- ; HercView.asm -- displays a text file on the screen using
- ; the Hercules board's graphics mode.
-
- dos equ 21h ;the DOS interrupt vector
-
- @rddev equ 3fh ;read a device
- @exit equ 04ch ;terminate process
-
- select equ 03b4h ;select 6845 register
-
- mode equ 03b8h ;display mode control port
- config equ 03bfh ;software configuation port
-
- cr equ 0dh
-
- ; use the following line if you want to use graphics page 1
- ; hires equ 0b800h ;segment for graphics page one
-
- hires equ 0b000h ;segment for graphics page zero
-
- buf equ [0080h] ;our buffer
-
- entry proc near
- mov ax,hires ;first put the segment of the graphics
- mov es,ax ; screen into ES
-
- call grafon ;turn on graphics mode
-
- init call grafclr ;and clear the screen
- movw lmarg,0 ;set left margin to zero for first pass
-
- init2 mov ax,lmarg ;set xcoord equal to left margin
- mov xcor,ax
- xor ax,ax ;set ycoord equal to top of screen
- mov ycor,ax
-
- next mov ah,@rddev ;read one character from stdin
- xor bx,bx ;stdin == device number zero
- mov cx,1 ;load one character
- mov dx,offset(buf) ;into our buffer
- int dos ;do it, DOS, please
-
- test ax,ax ;are we at EOF?
- jz done
-
- ; at this point, ax = 0001h.
-
- mov al,buf ;what character did we get?
-
- cmp al,cr ;carriage return?
- jnz ncr
-
- ; for simplicity, the only control character that the program reacts
- ; to is CR. CR performs a CR/LF on the screen. Thus, nonstandard
- ; text files which use LFs withour CRs for multiple blank lines
- ; will lose the blank lines.
-
- mov al,lmarg ;set xcoord back to left margin
- mov xcor,al
- addb ycor,2 ;bump the ycoord by two (will explain later)
-
- cmpb ycor,86 ;are we at the bottom of the screen?
- jb next ;no, continue processing
-
- xorb lmarg,90 ;yes, toggle left margin from 0 <-> 90(dec)
- jnz init2 ;if we are on second half, do partial init
-
- ; at this point, the entire screen has been filled with stuff
- call wait ;wait for a keypress
- jmps init ;and start the whole thing over
-
- ncr sub al,20h ;is it a control character?
- jb next ;yes, ignore it.
-
- ; formula is
- ; address == offset(table start) + (asc(char) - 32(dec) ) * 8
-
- shl ax ;remember, ah is already zero
- shl ax
- shl ax ;there, multiplied by 8
-
- add ax,offset(table)
- mov dot,ax ;save the address
- call plot ;and plot the character
-
- incb xcor ;advance cursor
-
- jmps next ;and do it again
-
- done call wait ;let user see last screen
- call texton ;and switch to text mode
- jmp byebye ;then return to DOS
-
- ; the only data for this section:
-
- lmarg dw 0 ;current left margin
-
- endp entry
-
- ; turn on graphics mode
-
- grafon proc near
- mov dx,config ;prepare to configure card
- ; use the following line if you want to use graphics page one
- ; mov al,3 ;turn on all options
-
- mov al,1 ;permit graphics but disable page one
- out dx,al
-
- mov si,offset(gtbl) ;config card using table
- call setmode
-
- mov dx,mode ;set graphics page
- ; use the following line if you want to use graphics page one
- ; mov al,0aah ;use graphics page one
-
- mov al,02ah ;use graphics page zero
- out dx,al
- ret
-
- ; table for proper graphics initialization
-
- gtbl db 35h,2dh,2eh,7,5bh,2,57h,57h,2,3,0,0
- endp
-
- ; turn off graphics mode
-
- texton proc near
- mov si,offset(ttbl) ;config card using table
- call setmode
-
- mov dx,mode ;set text mode
- mov al,028h ;page zero text
- out dx,al
- ret
-
- ; table to deactivate graphics
-
- ttbl db 61h,50h,52h,0fh,19h,6,19h,19h,2,0dh,0bh,0ch
- endp
-
- ; takes a table address passed in si and initializes the Herc card
- ; accordingly.
-
- setmode proc near
- cld ;move forwards through list
-
- mov dx,mode ;blank the screen, so we don't zap
- xor al,al ; the monitor
- out dx,al
-
- mov dx,select
- mov cx,11 ;table is 11 bytes long
- xor ah,ah
-
- setm1 mov al,ah ; port select <- register number
- out dx,al
- inc dx
- lodsb ; port (select+1) <- register value
- out dx,al
- dec dx
- inc ah
- loop setm1
- ret
- endp
-
- ; plot takes the coordinates in xcoord and ycoord and plots a character
- ; on the screen. The address for the character definition is contained
- ; in dot.
-
- ; The screen coordinates are 0 <= x <= 180 and 0 <= y <= 87.
- ; (Physical screen coordinates are 720 x 348, but to simplify the
- ; calculations, we plot in chunks of 4 x 4 pixels.)
- ; Since characters are 8 dots high, we need to increment ycoord
- ; twice to get to the next line.)
-
- plot proc near
-
- ; formula is
- ; address == (ycoord * 90 (dec)) + (xcoord DIV 2)
-
- mov al,ycor
- mulb ninety
-
- mov bx,xcor
- shr bx
- add bx,ax
-
- ; dl == screen mask. (MSB is displayed on the left)
- ; xcoord even: mask == 0f0h
- ; xcoord odd: mask == 00fh
-
- mov dl,0fh
- testb xcor,1
- jnz plot1
- not dl
-
- plot1
- mov si,dot ;si holds address of character descriptor
- cld ;move forwards
- mov cx,4 ;do first four rows
-
- ; screen mapping is sort of weird, so we have to plot the character
- ; in two parts.
-
- plot2 lodsb
- xor al,es:[bx] ;put the byte on the screen
- and al,dl
- xor es:[bx],al
-
- add bx,2000h ;move down a physical row
- loop plot2
-
- ; 32678 == 08000h - 90 (dec)
- sub bx,32678 ;move down another row
- mov cx,4 ;do the last four rows
-
- plot3 lodsb
- xor al,es:[bx] ;put the byte on the screen
- and al,dl
- xor es:[bx],al
-
- add bx,2000h ;move down another row
- loop plot3
-
- ; all done
- ret
-
- ycor dw 0
- xcor dw 0
- dot dw 0 ;address of picture box (4 x 4 pixels)
-
- ninety db 90 ;constant
-
- endp
-
- ; erase the graphics screen by writing zeros to the whole thing
-
- grafclr proc near
- cld ;move forwards
- mov di,0 ;di points into the screen
- xor ax,ax
- mov cx,4000h ;4000h words == 8000h bytes
-
- rep ;write 8000h zeros
- stosw
-
- ret
-
- endp
-
- ; pause for a keypress. If the user type ctrl-break or ctrl-c,
- ; the program exits.
-
- wait proc near
- xor ah,ah ;call BIOS keyboard routine
- int 016h
-
- cmp al,0 ;ctrl-break typed?
- jz bye
-
- cmp al,3 ;ctrl-c typed?
- jz bye
-
- ret ;no, return to caller
-
- bye pop ax ;clean the stack. (not really necessary)
- endp ;fall through to byebye routine.
-
- byebye proc near
- call texton ;reactivate text screen
- mov ah,@exit
- xor al,al ;no error code
- int dos ;say goodnight, Gracie.
- endp
-
- ; after assembling, use DEBUG to append the graphics table here.
-
- table ds 0